home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / CPP / WFC010.ZIP / SAMPLE / PINGER / PINGER.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-02  |  12.6 KB  |  444 lines

  1. #include <wfc.h>
  2. #include "messages.h"
  3. #pragma hdrstop
  4.  
  5. /*
  6. ** Author: Samuel R. Blackburn
  7. ** CI$: 76300,326
  8. ** Internet: sammy@sed.csc.com
  9. **
  10. ** $Date: $
  11. ** $Revision: $
  12. **
  13. ** This is freeware as always...
  14. **
  15. ** You can use it any way you like.
  16. **
  17. ** Sample program that watches other services and restarts them if they fail.
  18. **
  19. ** Registration Database Entries:
  20. **
  21. ** MachineName, REG_SZ, name of machine to monitor, default is local machine
  22. ** NumberOfMinutesBetweenPings, REG_DWORD, how long to sleep between heartbeats
  23. ** StartOnMinuteNumber, REG_DWORD, minute number to begin pinging (0 = top of the hour)
  24. **
  25. ** Demonstrates the following classes in action:
  26. **   CRegistry
  27. **   CService 
  28. **   CServiceControlManager
  29. **   CServiceNameAndStatus
  30. */
  31.  
  32. #if defined( _DEBUG )
  33. #undef THIS_FILE
  34. static char BASED_CODE THIS_FILE[] = __FILE__;
  35. #endif
  36.  
  37. HANDLE g_TimerEvent;
  38.  
  39. DWORD WINAPI worker_thread( LPVOID unused_parameter );
  40. DWORD WINAPI timer_thread( LPVOID unused_parameter );
  41. VOID set_default_parameters( DWORD, CString&, DWORD );
  42. VOID show_usage( LPSTR progam_name );
  43.  
  44. int __cdecl main( int argc, LPTSTR *argv )
  45. {
  46.    if ( argc == 1 )
  47.    {
  48.       CService service( worker_thread );
  49.       service.Initialize( "Pinger" );
  50.  
  51.       return( EXIT_SUCCESS );
  52.    }
  53.  
  54.    if ( argc > 1 )
  55.    {
  56.       if ( strcmpi( argv[ 1 ], "install" ) == 0 )
  57.       {
  58.          if ( argc < 4 )
  59.          {
  60.             show_usage( argv[ 0 ] );
  61.             return( EXIT_SUCCESS );
  62.          }
  63.  
  64.          CServiceControlManager service_control_manager;
  65.  
  66.          service_control_manager.Open();
  67.  
  68.          if ( service_control_manager.Install( "Pinger", "Pinger", "%SystemRoot%\\System32\\Pinger.exe" ) != TRUE )
  69.          {
  70.             printf( "Install failed, please see Application Log for details\n" );
  71.          }
  72.  
  73.          DWORD minute_number = 0;
  74.  
  75.          if ( argc > 4 )
  76.          {
  77.             minute_number = atol( argv[ 4 ] );
  78.          }
  79.  
  80.          set_default_parameters( atol( argv[ 2 ] ), CString( argv[ 3 ] ), minute_number );
  81.  
  82.          return( EXIT_SUCCESS );
  83.       }
  84.       else if ( strcmpi( argv[ 1 ], "remove" ) == 0 )
  85.       {
  86.          CServiceControlManager service_control_manager;
  87.  
  88.          service_control_manager.Open();
  89.  
  90.          if ( service_control_manager.Remove( "Pinger" ) != TRUE )
  91.          {
  92.             printf( "Removing failed, please see Application Log for details\n" );
  93.          }
  94.  
  95.          return( EXIT_SUCCESS );
  96.       }
  97.       else if ( strcmpi( argv[ 1 ], "run" ) == 0 )
  98.       {
  99.          worker_thread( (LPVOID) 1 );
  100.          return( EXIT_SUCCESS );
  101.       }
  102.       else
  103.       {
  104.          show_usage( argv[ 0 ] );
  105.       }
  106.    }
  107.    else
  108.    {
  109.       show_usage( argv[ 0 ] );
  110.    }
  111.  
  112.    return( EXIT_SUCCESS );
  113. }
  114.  
  115.  
  116. DWORD WINAPI worker_thread( LPVOID )
  117. {
  118.    {
  119.       CEventLog log( "Pinger" );
  120.  
  121.       log.Report( CEventLog::eventInformation, 0, MSG_PINGER_SERVICE_STARTED );
  122.    }
  123.  
  124.    DWORD number_of_minutes_to_sleep = 0;
  125.    DWORD minute_number;
  126.    CString machine_name( "" );
  127.  
  128.    BOOL return_value = TRUE;
  129.  
  130.    {
  131.       CRegistry registry;
  132.  
  133.       if ( registry.Connect( CRegistry::keyLocalMachine ) != TRUE )
  134.       {
  135.          return( 0 );
  136.       }
  137.  
  138.       CString key_name( "SYSTEM\\CurrentControlSet\\Services\\Pinger\\Parameters" );
  139.  
  140.       if ( registry.Open( key_name ) != TRUE )
  141.       {
  142.          return( 0 );
  143.       }
  144.  
  145.       registry.GetValue( "StartOnMinuteNumber", minute_number );
  146.       registry.GetValue( "NumberOfMinutesBetweenPings", number_of_minutes_to_sleep );
  147.       registry.GetValue( "MachineName", machine_name );
  148.    }
  149.  
  150.    CString command_line;
  151.  
  152.    DWORD sleep_time = 1000 * number_of_minutes_to_sleep * 60;
  153.  
  154.    if ( sleep_time < 2000 )
  155.    {
  156.       /*
  157.       ** Minimum sleep time is 2 seconds, this give the OS time to do other things
  158.       */
  159.  
  160.       sleep_time = 2000;
  161.    }
  162.  
  163.    if ( machine_name.IsEmpty() )
  164.    {
  165.       machine_name = "20.1.10.27";
  166.    }
  167.  
  168.    if ( minute_number > 59 )
  169.    {
  170.       minute_number = 0;
  171.    }
  172.  
  173.    /*
  174.    ** Construct our command line
  175.    */
  176.  
  177.    command_line = "ping ";
  178.    command_line += machine_name;
  179.  
  180.    /*
  181.    ** Wait until our minute rolls around
  182.    */
  183.  
  184.    CTime current_time = CTime::GetCurrentTime();
  185.  
  186.    while( current_time.GetMinute() != (int) minute_number )
  187.    {
  188.       Sleep( 900 );
  189.       current_time = CTime::GetCurrentTime();
  190.    }
  191.  
  192.    g_TimerEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
  193.  
  194.    if ( g_TimerEvent == (HANDLE) NULL )
  195.    {
  196.       LPVOID message_buffer = (LPVOID) NULL;
  197.  
  198.       ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  199.                        NULL,
  200.                        GetLastError(),
  201.                        MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ),
  202.              (LPTSTR) &message_buffer,
  203.                        0,
  204.                        NULL );
  205.  
  206.       const char *string_array[ 1 ];
  207.  
  208.       string_array[ 0 ] = (const char *) message_buffer;
  209.  
  210.       CEventLog event_log( "Pinger" );
  211.       event_log.Report( CEventLog::eventError, 0, MSG_CANT_CREATE_TIMER_EVENT, 1, (const char **) string_array );
  212.  
  213.       if ( message_buffer != NULL )
  214.       {
  215.          ::LocalFree( message_buffer );
  216.       }
  217.  
  218.       return( 0 );
  219.    }
  220.  
  221.    DWORD timer_thread_id = 0;
  222.  
  223.    if ( CreateThread( NULL, 0, timer_thread, (LPVOID) sleep_time, 0, &timer_thread_id ) == (HANDLE) NULL )
  224.    {
  225.       LPVOID message_buffer = (LPVOID) NULL;
  226.  
  227.       ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  228.                        NULL,
  229.                        GetLastError(),
  230.                        MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ),
  231.              (LPTSTR) &message_buffer,
  232.                        0,
  233.                        NULL );
  234.  
  235.       const char *string_array[ 1 ];
  236.  
  237.       string_array[ 0 ] = (const char *) message_buffer;
  238.  
  239.       CEventLog event_log( "Pinger" );
  240.       event_log.Report( CEventLog::eventError, 0, MSG_CANT_CREATE_TIMER_THREAD, 1, (const char **) string_array );
  241.  
  242.       if ( message_buffer != NULL )
  243.       {
  244.          ::LocalFree( message_buffer );
  245.       }
  246.  
  247.       return( 0 );
  248.    }
  249.  
  250.    do
  251.    {
  252.       WinExec( command_line, SW_HIDE );
  253.       WaitForSingleObject( g_TimerEvent, INFINITE );
  254.    }
  255.    while( 1 );
  256.  
  257.    return( 0 );
  258. }
  259.  
  260. DWORD WINAPI timer_thread( LPVOID pulse_interval )
  261. {
  262.    do
  263.    {
  264.       MessageBeep( MB_OK );
  265.       PulseEvent( g_TimerEvent );
  266.       Sleep( (DWORD) pulse_interval );
  267.    }
  268.    while( 1 );
  269.  
  270.    return( 0 );
  271. }
  272.  
  273. void set_default_parameters( DWORD number_of_minutes_to_sleep, CString& machine_name, DWORD minute_number )
  274. {
  275.    if ( number_of_minutes_to_sleep == 0 )
  276.    {
  277.       number_of_minutes_to_sleep = 1;
  278.    }
  279.  
  280.    if ( machine_name.IsEmpty() )
  281.    {
  282.       machine_name = "20.1.10.27";
  283.    }
  284.  
  285.    if ( minute_number > 59 )
  286.    {
  287.       minute_number = 0;
  288.    }
  289.  
  290.    CRegistry registry;
  291.  
  292.    if ( registry.Connect( CRegistry::keyLocalMachine ) == TRUE )
  293.    {
  294.       if ( registry.Create( "SYSTEM\\CurrentControlSet\\Services\\Pinger\\Parameters" ) == TRUE )
  295.       {
  296.          /*
  297.          ** Save the number of minutes between pings
  298.          */
  299.  
  300.          if ( registry.SetValue( "NumberOfMinutesBetweenPings", number_of_minutes_to_sleep ) != TRUE )
  301.          {
  302.             LPVOID message_buffer = (LPVOID) NULL;
  303.  
  304.             ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  305.                              NULL,
  306.                              registry.GetErrorCode(),
  307.                              MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ),
  308.                    (LPTSTR) &message_buffer,
  309.                              0,
  310.                              NULL );
  311.  
  312.             const char *string_array[ 2 ];
  313.  
  314.             string_array[ 0 ] = "SYSTEM\\CurrentControlSet\\Services\\Pinger\\Parameters\\NumberOfMinutesBetweenPings";
  315.             string_array[ 1 ] = (const char *) message_buffer;
  316.  
  317.             CEventLog event_log( "Pinger" );
  318.             event_log.Report( CEventLog::eventError, 0, MSG_CANT_SET_REGISTRY_ENTRY, 2, (const char **) string_array );
  319.  
  320.             if ( message_buffer != NULL )
  321.             {
  322.                ::LocalFree( message_buffer );
  323.             }
  324.          }
  325.  
  326.          /*
  327.          ** Now save the name of the machine to ping
  328.          */
  329.  
  330.          if ( registry.SetValue( "MachineName", machine_name ) != TRUE )
  331.          {
  332.             LPVOID message_buffer = (LPVOID) NULL;
  333.  
  334.             ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  335.                              NULL,
  336.                              registry.GetErrorCode(),
  337.                              MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ),
  338.                    (LPTSTR) &message_buffer,
  339.                              0,
  340.                              NULL );
  341.  
  342.             const char *string_array[ 2 ];
  343.  
  344.             string_array[ 0 ] = "SYSTEM\\CurrentControlSet\\Services\\Pinger\\Parameters\\MachineName";
  345.             string_array[ 1 ] = (const char *) message_buffer;
  346.  
  347.             CEventLog event_log( "Pinger" );
  348.             event_log.Report( CEventLog::eventError, 0, MSG_CANT_SET_REGISTRY_ENTRY, 2, (const char **) string_array );
  349.  
  350.             if ( message_buffer != NULL )
  351.             {
  352.                ::LocalFree( message_buffer );
  353.             }
  354.          }
  355.  
  356.          /*
  357.          ** Save the minute number to begin on
  358.          */
  359.  
  360.          if ( registry.SetValue( "StartOnMinuteNumber", minute_number ) != TRUE )
  361.          {
  362.             LPVOID message_buffer = (LPVOID) NULL;
  363.  
  364.             ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  365.                              NULL,
  366.                              registry.GetErrorCode(),
  367.                              MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ),
  368.                    (LPTSTR) &message_buffer,
  369.                              0,
  370.                              NULL );
  371.  
  372.             const char *string_array[ 2 ];
  373.  
  374.             string_array[ 0 ] = "SYSTEM\\CurrentControlSet\\Services\\Pinger\\Parameters\\StartOnMinuteNumber";
  375.             string_array[ 1 ] = (const char *) message_buffer;
  376.  
  377.             CEventLog event_log( "Pinger" );
  378.             event_log.Report( CEventLog::eventError, 0, MSG_CANT_SET_REGISTRY_ENTRY, 2, (const char **) string_array );
  379.  
  380.             if ( message_buffer != NULL )
  381.             {
  382.                ::LocalFree( message_buffer );
  383.             }
  384.          }
  385.       }
  386.       else
  387.       {
  388.          LPVOID message_buffer = (LPVOID) NULL;
  389.  
  390.          ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  391.                           NULL,
  392.                           registry.GetErrorCode(),
  393.                           MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ),
  394.                 (LPTSTR) &message_buffer,
  395.                           0,
  396.                           NULL );
  397.  
  398.          const char *string_array[ 2 ];
  399.  
  400.          string_array[ 0 ] = "SYSTEM\\CurrentControlSet\\Pinger\\WatchDog\\Parameters";
  401.          string_array[ 1 ] = (const char *) message_buffer;
  402.  
  403.          CEventLog event_log( "Pinger" );
  404.          event_log.Report( CEventLog::eventError, 0, MSG_CANT_CREATE_REGISTRY_KEY, 2, (const char **) string_array );
  405.  
  406.          if ( message_buffer != NULL )
  407.          {
  408.             ::LocalFree( message_buffer );
  409.          }
  410.       }
  411.    }
  412.    else
  413.    {
  414.       LPVOID message_buffer = (LPVOID) NULL;
  415.  
  416.       ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  417.                        NULL,
  418.                        registry.GetErrorCode(),
  419.                        MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ),
  420.              (LPTSTR) &message_buffer,
  421.                        0,
  422.                        NULL );
  423.  
  424.       const char *string_array[ 2 ];
  425.  
  426.       string_array[ 0 ] = "keyLocalMachine";
  427.       string_array[ 1 ] = (const char *) message_buffer;
  428.  
  429.       CEventLog event_log( "Pinger" );
  430.       event_log.Report( CEventLog::eventError, 0, MSG_CANT_CONNECT_TO_REGISTRY, 2, (const char **) string_array );
  431.  
  432.       if ( message_buffer != NULL )
  433.       {
  434.          ::LocalFree( message_buffer );
  435.       }
  436.    }
  437. }
  438.  
  439. VOID show_usage( LPSTR program_name )
  440. {
  441.    printf( "Pinger service, Samuel R. Blackburn, WFC Sample Application\n\nUsage: %s [install SleepTime MachineName StartMinute|remove|run]\n\n", program_name );
  442.    printf( "To have explorer.sed.csc.com ping'd every 60 minutes begining at the top of\nthe hour, type:\n%s install 60 explorer.sed.csc.com 0\n\n\n", program_name );
  443.    printf( "This service is great for keep RAS connections open when they automatically\nclose after a certain amount of time passes without any traffic over the\nconnection.\n" );
  444. }